const path = require('path');
const _ = require('lodash');
const fs = require('fs-extra');

function getSingleDomains(filename = 'domain.config.js') {
  const domainConfigPath = path.resolve(process.cwd(), 'domain', filename);
  if (fs.pathExistsSync(domainConfigPath)) {
    return Object.keys(require(domainConfigPath).getSingleDomains());
  }
}

/**
 * 加载本地领域配置文件
 * @param {string} filename 
 * @param {object} defaultValue 
 */
function loadLocalDomainConfig(filename, defaultValue) {
  const domainConfigPath = path.resolve(process.cwd(), filename);
  if (fs.pathExistsSync(domainConfigPath)) {
    const localDomainConfig = require(domainConfigPath);
    return localDomainConfig.domainConfig || localDomainConfig;
  }
  {
    const domainConfigPath = path.resolve(process.cwd(), 'domain', filename);
    if (fs.pathExistsSync(domainConfigPath)) {
      const localDomainConfig = require(domainConfigPath);
      return localDomainConfig.domainConfig || localDomainConfig;
    }
  }
  return defaultValue;
}

/**
 * 领域路径映射 domain ==> srcpath 跨域引用时自动生成 exposes 列表
 */
const DomainConfig = loadLocalDomainConfig('domain.config.js', { thirdlib: 'thirlib' });

/**
 * 领域路径映射反转  srcpath ==> domain
 */
const ReverseDomainConfig = Object.fromEntries(Object.entries(DomainConfig).map(([domain, srcpath]) => [srcpath, domain]));
const DomainNameList = Object.keys(DomainConfig);
const DomainPathList = Object.values(DomainConfig);

// 过滤非src 或 @remote 开头的
const DomainPathListFilter = DomainPathList.filter((domainPath) => /^(src|@remote)/.test(domainPath) === false);

/**
 * 开发域
 * 本地开发环境下，通过环境变量**DEVDOMAIN**定义,多个域使用,分割
 * 建议在 .env.local 中定义 例如: DEVDOMAIN=mdf-metapage,mdf-ui
 */
const devDomain = (process.env.DEVDOMAIN || '').split(',');
const onlyThirdLib = process.env.ONLY_THIRDLIB_REMOTE === 'true';

/**
 * 远程域
 * key 为领域名称, value 为领域模块引用前辍
 */
const RemoteDomain = onlyThirdLib ? _.pick(DomainConfig, ['thirdlib']) : _.omit(DomainConfig, devDomain);

/**
 * 返回当前路径所属域
 * @param {string} filePath
 * @param {string} rootPath
 */
const getDomain = (filePath, rootPath) => {
  // 领域目录 只能包含字母、数字、中横线、下划线
  const matcher = filePath.match(/(@remote|src)\/([a-zA-Z0-9-_]+)/);

  if (matcher === null) return null;

  const srcPath = matcher[0];
  const fullpath = path.resolve(rootPath, srcPath);
  const name = ReverseDomainConfig[srcPath] || null;

  return { name, srcPath, fullpath };
};

/**
 * 判断模块路径是否属于远程域
 * @param {string} modulePath
 */
const isRemoteDomain = (modulePath) => {
  return DomainPathListFilter.some((domainpath) => modulePath.startsWith(domainpath));
};

module.exports = {
  ReverseDomainConfig,
  isRemoteDomain,
  getDomain,
  DomainConfig,
  RemoteDomain,
  getSingleDomains,
};
